package com.jy.api.service.impl;

import com.jy.api.dao.*;
import com.jy.api.domain.*;
import com.jy.api.service.EmployeeService;
import com.jy.api.service.ProductService;
import com.jy.api.service.StoreService;
import com.jy.api.signUpReq.MarsCallReq.MarsCallRes;
import com.jy.api.signUpReq.MarsCallReq.SetStoreCallTime;
import com.jy.api.signUpReq.MarsCallReq.UpdateRewardReq;
import com.jy.api.signUpReq.MarsCallReq.UpdateStoreReq;
import com.jy.api.signUpReq.SalesCode.MyStoreRes;
import com.jy.api.signUpReq.SalesCode.UpdateSalesCodeReq;
import com.jy.api.signUpReq.admin.SetPswReq;
import com.jy.api.signUpReq.admin.StoreReq;
import com.jy.api.signUpReq.admin.StoreSignUpReq;
import com.jy.api.signUpReq.admin.StoreUpdateReq;
import com.jy.api.util.*;
import com.jy.api.util.Result;
import com.jy.api.vo.admin.store.StoreVo;
import com.jy.api.vo.member.StoreMemberInfoVo;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import sun.misc.BASE64Encoder;

import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class StoreServiceImpl implements StoreService {

    @Autowired
    StoreDao storeDao;

    @Autowired
    StoreProfileDao storeProfileDao;

    @Autowired
    EmployeeService employeeService;

    @Autowired
    SalesUrlUtil salesUrlUtil;
    @Autowired
    private EmployeeDao employeeDao;
    @Autowired
    MemberAccountDao memberAccountDao;

    @Autowired
    private StoreTypeDao storeTypeDao;

    @Autowired
    private TableSalesCodeDao codeDao;


    @Override
    public List<StoreVo> getStores(String userName, boolean status) throws ParseException {
        List<StoreVo> storeVos = new ArrayList<>();
        List<String> storeIds = null;
        if (status) {
            storeIds = employeeService.getStoreIds(userName);
        } else {
            storeIds = employeeService.getStoresPartner(userName);
        }

        List<Map<String, Object>> stores = storeDao.getStoreList(userName, storeIds);
        for (Map<String, Object> map : stores) {
            StoreVo storeVo = new StoreVo(map.get("id").toString(), map.get("name").toString(),
                    map.get("addr").toString(), map.get("referralCode").toString(),
                    map.get("addTime") != null ? MyDateUtils.stringToDate(map.get("addTime").toString()) : new Date(),
                    map.get("updateTime") != null ? MyDateUtils.stringToDate(map.get("updateTime").toString()) : new Date(),
                    map.get("typeCode").toString(), Boolean.valueOf(map.get("call").toString()));
            storeVos.add(storeVo);
        }
        return storeVos;
    }

    @Override
    @Transactional
    public Store addStore(String storeId, StoreSignUpReq storeOrder,
                          String username, StoreType storeType) throws IOException {
        Store store = storeDao.findOne(storeId);
        if (store == null) {
            store = new Store();
            BeanUtils.copyProperties(storeOrder, store);
            store.setId(storeId);
            store.setUsername(username);
            employeeService.addEmployee(store, username);
        } else {
            store.setName(storeOrder.getName());
            store.setAddr(storeOrder.getAddr());
        }
        if (!StringUtils.equals(store.getTypeCode(),
                storeType.getCode())) {
            store.setTypeCode(storeType.getCode());
            store.setTypeName(storeType.getName());
        }
        reduceCode(storeOrder.getReferralCode());
        store.setReferralCode(storeOrder.getReferralCode());
        //默认过期时间为 修改推荐码后1个月
        store.setExpireTime(MyDateUtils.increaseMonth(new Date(), 1));
        storeDao.save(store);
        return store;
    }


    /**
     * 修改店铺简介
     *
     * @param storeReq
     */
    @Override
    @Transactional
    public void updateStore(StoreReq storeReq) {
        Store store = storeDao.findOne(storeReq.getStoreId());
        store.setStoreLogo(storeReq.getLogo());
        store.setSummary(storeReq.getDetail());
        storeDao.save(store);
    }

    public void reduceCode(String code) throws IOException {
        TableSalesCode salesCode = codeDao.findByCodeAndEnabled(code, true);
        salesCode.setCount(salesCode.getCount() - 1);
        codeDao.save(salesCode);
    }

    @Override
    @Transactional
    public void updatePaymentCfg(String storeId, String mchId, String key) throws StoreProfileNotExistException {
        StoreProfile profile = storeProfileDao.findByStoreId(storeId);
        if (null == profile) {
            throw new StoreProfileNotExistException();
        }

        profile.setStatus(StoreProfileStatus.APPROVED);


        Store store = storeDao.findOne(storeId);

        store.setMchId(mchId);
        store.setKey(key);


    }

    @Override
    public Page<StoreProfile> getALLProfile(String userName, Pageable pageable) {
        if (StringUtils.equals("13980547109", userName)) {
            Page<StoreProfile> profile = storeProfileDao.findByEnabledOrderByStatusDesc(true, pageable);
            return profile;
        }else {
            return null;
        }
    }

    @Override
    public List<com.jy.api.vo.member.StoreVo> getMemberStoreLike(String memberId, String q) {
        List<Object[]> objects = storeDao.queryLikeStoreName(memberId, q);
        List<com.jy.api.vo.member.StoreVo> storeVos = objects.stream().map(e ->
                new com.jy.api.vo.member.StoreVo(e[0].toString(), e[1].toString(), e[2].toString())
        ).collect(Collectors.toList());
        return storeVos;
    }

    @Override
    public List<com.jy.api.vo.member.StoreVo> getMemberAllStoreLike(String q) {
        List<Store> objects = storeDao.queryLikeStoreNameAll(q);
        List<com.jy.api.vo.member.StoreVo> storeVos = objects.stream().map(e ->
                new com.jy.api.vo.member.StoreVo(e.getId(), e.getName(), e.getAddr())
        ).collect(Collectors.toList());
        return storeVos;
    }

    @Override
    public List<StoreMemberInfoVo> getStoreIndo(String memberId, Pageable pageable) {
        List<StoreMemberInfoVo> storeMemberInfoVos = new ArrayList<>();
        List<Map<String, Object>> maps = memberAccountDao.queryStoreInfo(memberId, pageable);

        List<String> storeIds = maps.stream().map(e -> e.get("storeId").toString()).collect(Collectors.toList());
        if (storeIds.size() > 0) {
            Map<String, Store> stores = storeDao.findByIdIn(storeIds).stream()
                    .collect(Collectors.toMap(Store::getId, store -> store));
            for (Map<String, Object> map : maps) {
                Store store = stores.get(map.get("storeId").toString());
                StoreMemberInfoVo storeMemberInfoVo = new StoreMemberInfoVo(store.getId(), store.getName(),
                        store.getAddr(), Double.parseDouble(map.get("amount").toString()), Integer.parseInt(map.get("points").toString()));
                storeMemberInfoVos.add(storeMemberInfoVo);
            }
        }

        return storeMemberInfoVos;
    }

    @Override
    public String creatClient(String storeId) {

        //文件夹路径
        //配置文件路径
        String fileKey = "client/" + storeId + "/config.ini";
        try {
            //生成配置参数并且上传到OSS
            ImageFileOssUtil.imageUpload(new ByteArrayInputStream(StoreConfigUtil.CLIENT_CONFIG.replace("STORE_ID", storeId).getBytes()), fileKey);
            fileKey = ImageFileOssUtil.getUrl(fileKey);
        } catch (FileNotFoundException e) {
            log.error("文件未找到", e);
        }
        return fileKey;
    }

    @Override
    public String creatClientBat(String storeId) {
        //文件夹路径
        //配置文件路径
        String fileKey = "client/" + storeId + "/ie.bat";
        try {
            //生成配置参数
            ImageFileOssUtil.imageUpload(new ByteArrayInputStream(StoreConfigUtil.CLIENT_BAT_CONFIG.replace("STORE_ID", storeId).getBytes()), fileKey);
            fileKey = ImageFileOssUtil.getUrl(fileKey);
        } catch (FileNotFoundException e) {
            log.error("文件未找到", e);
        }
        return fileKey;
    }

    //
    public String getUrl(String storeId) {
        String fileKey = "tableClient/" + storeId + ".zip";
        try {
            ImageFileOssUtil.downloadAndUpload(storeId);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String url = ImageFileOssUtil.getUrl(fileKey);
        return url;


    }


    /**
     * 查找呼叫首页信息
     *
     * @param storeId
     * @return
     */
    @Override
    public MarsCallRes findMarsCallIndex(String storeId) {
        Store store = storeDao.findOne(storeId);
        if (store == null) {
            return new MarsCallRes();
        }
        if (store.isCall() && new Date().getTime() - store.getCallEndTime().getTime() < 0) {
            List<Employee> list = employeeDao.findListByStoreIdAndEnabledOrderByWorkDesc(storeId, true);
            List<MarsCallRes.Emp> emps = new ArrayList<>();
            MarsCallRes marsCallRes = new MarsCallRes();
            marsCallRes.setSummary(store.getSummary());
            marsCallRes.setLogo(store.getStoreLogo());
            marsCallRes.setStoreName(store.getName());
            int count = 0;
            for (Employee employee : list) {
                if (employee.getGroup().isShow()) {
                    if (!employee.getGroup().getId().equals("1")) {
                        MarsCallRes.Emp marsEmp = new MarsCallRes.Emp();
                        marsEmp.setEmpId(employee.getId());
                        marsEmp.setEmpName(employee.getName());
                        marsEmp.setEmpPhoto(employee.getPhoto());
                        marsEmp.setEmpJob(employee.getGroup().getName());
                        marsEmp.setWork(employee.isWork());
                        marsEmp.setReward(employee.getGroup().isReward());
                        count = count + 1;
                        emps.add(marsEmp);
                    } else {
                        continue;
                    }
                } else {
                    continue;
                }
            }
            marsCallRes.setReward(store.isReward());
            marsCallRes.setEmpCount(count);
            marsCallRes.setEmps(emps);
            return marsCallRes;
        } else {
            MarsCallRes res = new MarsCallRes();
            res.setEmps(new ArrayList<>());
            return res;
        }
    }

    @Override
    public Map<String, Object> updateStoreByStoreId(UpdateStoreReq req) {
        Store store = storeDao.findOne(req.getStoreId());
        Map<String, Object> map = new HashMap<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        Date endTime = null;
        try {
            endTime = simpleDateFormat.parse(req.getCallEndTime());
        } catch (ParseException e) {
            log.info("时间转换异常");
            e.printStackTrace();
        }
        if (null == store.getCallTime()) {
            store.setCallTime(new Date());
        }
        store.setCall(req.isCall());
        if (null == store.getCallEndTime()) {
            if (store.isCall()) {
                try {
                    ImageFileOssUtil.downloadCallAndClientUpload(req.getStoreId());
                    ImageFileOssUtil.downloadCallAndServiceUpload(req.getStoreId());
                    ImageFileOssUtil.downloadXpCallAndClientUpload(req.getStoreId());
                } catch (IOException e) {
                    log.info("呼叫客户端/服务端生成异常");
                    e.printStackTrace();
                }
            }
        }
        store.setCallEndTime(endTime);
        storeDao.save(store);
        map.put("result", new Result(200, "修改成功"));
        return map;
    }

    @Override
    @Transactional
    public Result updateStoreByZero(UpdateRewardReq req) {
        Store store = storeDao.findOne(req.getStoreId());
        store.setZero(req.isZero());
        storeDao.save(store);
        return new Result(200, "修改成功");
    }

    @Override
    @Transactional
    public Result updateStoreByDiscount(UpdateRewardReq req) {
        Store store = storeDao.findOne(req.getStoreId());
        store.setDiscount(req.isDiscount());
        storeDao.save(store);
        return new Result(200, "修改成功");
    }

    @Override
    @Transactional
    public Map<String, Object> updateReward(UpdateRewardReq req) {
        Store store = storeDao.findOne(req.getStoreId());
        Map<String, Object> map = new HashMap<>();
        store.setReward(req.isReward());
        storeDao.save(store);
        map.put("result", new Result(200, "保存成功"));
        return map;
    }

    @Override
    public List<Store> likeStoreName(String name) {
        return storeDao.findByStoreNameLike(name);
    }

    @Override
    @Transactional
    public Map<String, Object> setStoreSecond(SetStoreCallTime callTime) {
        Map<String, Object> map = new HashMap<>();
        Store store = storeDao.findOne(callTime.getStoreId());
        store.setCallSecond(callTime.getSecond());
        Store returnStore = storeDao.save(store);
        map.put("result", new Result(200, "呼叫时间设置成功"));
        map.put("data", returnStore);
        return map;
    }

    @Override
    @Transactional
    public Map<String, Object> updateStoreById(StoreUpdateReq req) {
        Map<String, Object> map = new HashMap<>();
        StoreType storeType = storeTypeDao.findOne(req.getTypeId());
        Store store = storeDao.findOne(req.getStoreId());
        store.setName(req.getName());
        store.setAddr(req.getAddr());
        store.setTypeName(storeType.getName());
        store.setTypeCode(storeType.getCode());
        Store returnStore = storeDao.save(store);
        map.put("result", new Result(200, "保存成功"));
        map.put("data", returnStore);
        return map;
    }

    @Override
    public List<Store> findByStoreNameLike(String name) {
        return storeDao.findByStoreNameLike(name);
    }

    @Override
    public Result setPsw(SetPswReq req) {
        Store store = storeDao.findOne(req.getStoreId());
        store.setPsw(req.getPsw());
        storeDao.save(store);
        return new Result(200, "修改成功");
    }

    @Override
    public Result judgePsw(SetPswReq req) {
        Store store = storeDao.findOne(req.getStoreId());
        if (StringUtils.contains(req.getJudgePsw(), store.getPsw())) {
            return new Result(200, "密码正确");
        } else {
            return new Result(400, "密码错误");
        }
    }

    @Override
    public List<MyStoreRes> getMyStore(String userName) {
        TableSalesCode code = codeDao.findByUserName(userName);
        List<Store> store = storeDao.findByReferralCodeAndEnabledOrderByExpireTimeDesc(code.getCode(), true);
        List<MyStoreRes> res = new ArrayList<>();
        for (Store s : store) {
            MyStoreRes storeRes = new MyStoreRes();
            storeRes.setDate(s.getExpireTime());
            storeRes.setStoreName(s.getName());
            res.add(storeRes);
        }
        return res;
    }

    @Override
    public Page<Store> getAllStore(String userName, Pageable pageable) {
        if (StringUtils.equals("13980547109", userName)) {
            Page<Store> store = storeDao.findAllByEnabledOrderByExpireTimeDesc(true, pageable);
            return store;
        } else {
            return null;
        }
    }

    @Override
    public Result updateStoreExp(UpdateSalesCodeReq req) {
        Store store = storeDao.findOne(req.getStoreId());
        if (store == null) {
            return new Result(400, "店铺不存在");
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        try {
            store.setExpireTime(simpleDateFormat.parse(req.getExpTime()));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        store.setLevel(req.getLevel());
        storeDao.save(store);
        return new Result(200, "修改成功");
    }

    /**
     * @param data1
     * @param data2
     * @return data1 与 data2拼接的结果
     */
    public static byte[] addBytes(byte[] data1, byte[] data2) {
        byte[] data3 = new byte[data1.length + data2.length];
        System.arraycopy(data1, 0, data3, 0, data1.length);
        System.arraycopy(data2, 0, data3, data1.length, data2.length);
        return data3;

    }

}
